package com.geeguo.ebuilder.core.common.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.jackson.JsonComponent;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@JsonComponent
class DateFormatConfig {

    private static final List<DateFormat> FORMATS = new ArrayList<>(5);

    private static final String YYYY_MM                 = "^\\d{4}-\\d{1,2}$";
    private static final String YYYY_MM_DD              = "^\\d{4}-\\d{1,2}-\\d{1,2}$";
    private static final String YYYY_MM_DD_HH_MM        = "^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}$";
    private static final String YYYY_MM_DD_HH_MM_SS     = "^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}$";

    static {
        FORMATS.add(new SimpleDateFormat("yyyy-MM"));
        FORMATS.add(new SimpleDateFormat("yyyy-MM-dd"));
        FORMATS.add(new SimpleDateFormat("yyyy-MM-dd HH:mm"));
        FORMATS.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }

    private static final DateFormat SERIALIZE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 日期格式化
     */
    public static class DateJsonSerializer extends JsonSerializer<Date> {
        @Override
        public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeString(SERIALIZE_DATE_FORMAT.format(date));
        }
    }

    /**
     * 解析日期字符串
     */
    public static class DateJsonDeserializer extends JsonDeserializer<Date> {
        @Override
        public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            try {
                if (jsonParser.getText() != null) {
                    String value = jsonParser.getText().trim();
                    if (!value.isEmpty()) {
                        if (value.matches(YYYY_MM)) {
                            return FORMATS.get(0).parse(value);
                        } else if (value.matches(YYYY_MM_DD)) {
                            return FORMATS.get(1).parse(value);
                        } else if (value.matches(YYYY_MM_DD_HH_MM)) {
                            return FORMATS.get(2).parse(value);
                        } else if (value.matches(YYYY_MM_DD_HH_MM_SS)) {
                            return FORMATS.get(3).parse(value);
                        }
                    }
                }
                return null;
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
